#include "common.h"
// 服务端
int main()
{
    // 首先生成秘钥
    key_t key = ftok(PATH_NAME, PROJ_ID);
    // std::cout << key << std::endl;

    // 创建共享内存
    umask(0);  // 掩码
    int shmid = shmget(key, SHMSIZE, IPC_CREAT | IPC_EXCL | 0666);
    if (shmid < 0)
    {
        perror("shmget:");
        exit(1);
    }
    std::cout << "创建共享内存成功！" << std::endl;

    // 挂接到当前进程的共享区
    char* shmarr = (char*)shmat(shmid, nullptr, 0);  // 共享内存id 挂接形式... 操作
    if (*((int*)shmarr) < 0)
    {
        perror("shmat:");
        exit(2);
    }
    std::cout << getpid() << "进程挂接共享内存成功！" << std::endl;

    // 进程通信 服务端进行循环读取，由于是直接访问内存，所以没有阻塞，需要配合管道食用更佳
    while (true)
    {
        char* tmp = shmarr;
        if (strcmp(shmarr, "quit") == 0) break;
        printf("%s\n", tmp);
        sleep(1);
    }

    // 去关联 - 实际上服务端可以不用做这一步，因为服务端最后会将此共享内存给删除
    int s = shmdt(shmarr);
    if (s < 0)
    {
        perror("shmdt:");
        exit(2);
    }
    std::cout << getpid() << "进程去关联成功！" << std::endl;
    // 删除共享内存
    int m = shmctl(shmid, IPC_RMID, nullptr);  // 共享内存id 操作(当前操作是无论有多少个进程挂接上都会删除掉) null
    if (m < 0)
    {
        perror("shmctl:");
        exit(3);
    }
    std::cout << "删除共享内存成功！" << std::endl;

    return 0;
}